package com.dragon.common.spring.openapi.customizers.openapi;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springdoc.core.customizers.OpenApiCustomizer;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author Chris Chan
 * Create On 2025/10/2 上午11:20
 * Use for: 过滤OpenAPI文档中的路径，只保留标记了指定组的操作
 * Explain:
 */
@Order(1)
@Component
public class GroupFilterOpenApiCustomizer implements OpenApiCustomizer {
    private static final Logger log = LoggerFactory.getLogger(GroupFilterOpenApiCustomizer.class);
    private String group;

    public GroupFilterOpenApiCustomizer() {
    }

    public GroupFilterOpenApiCustomizer(String group) {
        this.group = group;
    }

    public static GroupFilterOpenApiCustomizer of(String group) {
        return new GroupFilterOpenApiCustomizer(group);
    }

    @Override
    public void customise(OpenAPI openApi) {
        log.info("GroupFilterOpenApiCustomizer~~");
        Paths paths = new Paths();
        // 用于收集所有被使用的标签
        Set<String> usedTags = new HashSet<>();
        AtomicInteger count = new AtomicInteger();

        openApi.getPaths().forEach((path, pathItem) -> {
            pathItem.readOperationsMap().forEach((httpMethod, operation) -> {
                Map<String, Object> extensions = operation.getExtensions();
                if (extensions != null) {
                    String apiGroup = (String) extensions.get("x-api-group");
                    if (Objects.equals(apiGroup, group)) {
                        //log.info("✅ 保留路径: {} {}, 分组: {}", httpMethod, path, apiGroup);
                        paths.addPathItem(path, pathItem);
                        count.getAndIncrement();

                        // 收集此操作上定义的标签
                        if (operation.getTags() != null) {
                            usedTags.addAll(operation.getTags());
                        }
                    }
                }
            });
        });

        openApi.setPaths(paths);
        //log.info("过滤完成，保留 {} 个路径", count);

        // 2. 清理全局未使用的Tags
        List<Tag> globalTags = openApi.getTags();
        if (globalTags != null) {
            // 保留那些在usedTags集合中存在的tag
            List<Tag> cleanedGlobalTags = globalTags.stream()
                    .filter(tag -> tag != null &&
                            tag.getName() != null &&
                            usedTags.contains(tag.getName()))
                    .collect(Collectors.toList());
            openApi.setTags(cleanedGlobalTags);
        }
    }

}
